# -*- coding: utf-8 -*-
import pprint
import sys
import time
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.button import Button
from kivy.uix.image import AsyncImage
from kivy.uix.recyclegridlayout import RecycleGridLayout
from kivy.uix.recycleview.layout import LayoutSelectionBehavior
from kivy.uix.recycleview.views import RecycleDataViewBehavior
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.config import Config
from kivy.core.window import Window
from kivy.properties import BooleanProperty
from kivy.uix.behaviors import FocusBehavior
import kivy.metrics
from BiliBiliSpider import settings
import pymysql
# 导入功能函数
from functools import partial
import re

# 这是解析默认字体，打包时自动读取包里的字体
Config.set('kivy', 'default_font', ["Roboto", "DroidSansFallback.ttf"])
# 设置UI界面大小
Window.size = (1024, 680)


# 以下为ui设计代码
class SpiderMainScreenManager(ScreenManager):
    """
        窗口管理类
    """

    def __init__(self, **kwargs):
        super(SpiderMainScreenManager, self).__init__(**kwargs)
        Window.bind(on_keyboard=self.on_key)
        self.count = 0
        self.screenName = None
        self.img_link_list = []
        self.video_link_list = []
        self.tx_img_link_list, self.tx_video_link_list = [], []
        self.yk_img_link_list, self.yk_video_link_list = [], []
        # 建立数据库连接
        self.connect = pymysql.connect(
            host=settings.HOST,
            db=settings.DATABASE,
            user=settings.USER,
            password=settings.PASSWORD,
            charset='utf8',
        )
        self.tx_connect = pymysql.connect(
            host=settings.HOST,
            db=settings.TX_DATABASE,
            user=settings.USER,
            password=settings.PASSWORD,
            charset='utf8',
        )
        self.yk_connect = pymysql.connect(
            host=settings.HOST,
            db=settings.YK_DATABASE,
            user=settings.USER,
            password=settings.PASSWORD,
            charset='utf8',
        )

        # 创建游标对象
        self.cursor = self.connect.cursor()
        self.tx_cursor = self.tx_connect.cursor()
        self.yk_cursor = self.yk_connect.cursor()
        # 调用数据库查询
        self.query_data()
        self.tx_query_data()
        self.yk_query_data()

    def query_data(self):
        """
        从数据库中查询需要的数据, 并处理
        :return:
        """
        query_sql = 'select * from video_info inner join video_number on video_info.anime_name = video_number.anime_name;'
        try:
            self.cursor.execute(query_sql)
        except Exception as e:
            print("数据库查询失败", e)
        # 将查询到的值提取出来
        self.query_data = self.cursor.fetchall()
        # (name, update_status, image_link, name, video_number, video_path)
        print("查询数据条数", len(self.query_data))
        for info in self.query_data:
            print("电影数据信息", info)
            # 提取图片链接列表, 列表里存有元组 (图片链接，动漫名字，以及更新状态(是否完结))
            self.img_link_list.append((info[2], info[0], info[1]))
            # 这是将集数中的数字提取出来, 并且转为int类型，方便后面进行集数的排序
            anime_number = int(re.findall(r'\d+', info[4], re.S)[-1])
            # 提取视频链接列表，列表里存有元组 (动漫名字，动漫集数，动漫视频链接)
            self.video_link_list.append((info[0], anime_number, info[5]))
        # 将列表转为集合去重再转为列表
        self.img_link_list = list(set(self.img_link_list))
        print(type(self.img_link_list), len(self.img_link_list), self.img_link_list)
        print(len(self.video_link_list), self.video_link_list)
        self.cursor.close()
        self.connect.close()

    def tx_query_data(self):
        """
        从数据库中查询需要的数据, 并处理
        :return:
        """
        query_sql = 'select * from tx_video_info inner join tx_video_number on tx_video_info.video_name = tx_video_number.video_name;'
        try:
            self.tx_cursor.execute(query_sql)
        except Exception as e:
            print("数据库查询失败", e)
        # 将查询到的值提取出来
        self.query_data = self.tx_cursor.fetchall()
        # (name, image_link, name, video_number, video_path)
        print("查询数据条数", len(self.query_data))
        for info in self.query_data:
            print("电影数据信息", info)
            # 提取图片链接列表, 列表里存有元组 (图片链接，动漫名字)
            self.tx_img_link_list.append((info[1], info[0]))
            # 提取视频链接列表，列表里存有元组 (动漫名字，动漫集数，动漫视频链接)
            self.tx_video_link_list.append((info[0], int(info[3]), info[4]))
        # 将列表转为集合去重再转为列表
        self.tx_img_link_list = list(set(self.tx_img_link_list))
        print(type(self.tx_img_link_list), len(self.tx_img_link_list), self.tx_img_link_list)
        print(len(self.tx_video_link_list), self.tx_video_link_list)
        self.tx_cursor.close()
        self.tx_connect.close()

    def yk_query_data(self):
        """
        从数据库中查询需要的数据, 并处理
        :return:
        """
        query_sql = 'select * from yk_video_info inner join yk_video_number on yk_video_info.video_name = yk_video_number.video_name;'
        try:
            self.yk_cursor.execute(query_sql)
        except Exception as e:
            print("数据库查询失败", e)
        # 将查询到的值提取出来
        self.query_data = self.yk_cursor.fetchall()
        print("查询数据条数", len(self.query_data))
        for info in self.query_data:
            print("电影数据信息", info)
            # 提取图片链接列表, 列表里存有元组 (图片链接，动漫名字)
            self.yk_img_link_list.append((info[1], info[0]))
            # 提取视频链接列表，列表里存有元组 (动漫名字，动漫集数，动漫视频链接)
            self.yk_video_link_list.append((info[0], int(info[3]), info[4]))
        # 将列表转为集合去重再转为列表
        self.yk_img_link_list = list(set(self.yk_img_link_list))
        print(type(self.yk_img_link_list), len(self.yk_img_link_list), self.yk_img_link_list)
        print(len(self.yk_video_link_list), self.yk_video_link_list)
        self.yk_cursor.close()
        self.yk_connect.close()

    def tx_add_all_links(self):
        """全部动漫添加新图片、新视频链接"""
        print("视频看看", self.children[0])
        root = self.children[0].ids['videoRecycleView']
        # 如果有元素，则删除
        if root.data:
            del root.data[:]
        for img_link in self.tx_img_link_list:
            root.data.insert(0, {
                "source": img_link[0],
                "size_hint": (0.5, None),
                "height": kivy.metrics.dp(150),
                "allow_stretch": True,
                "keep_ratio": False,
                'text': img_link[1],
            })

    def yk_add_all_links(self):
        """全部动漫添加新图片、新视频链接"""
        print("视频看看", self.children[0])
        root = self.children[0].ids['videoRecycleView']
        # 如果有元素，则删除
        if root.data:
            del root.data[:]
        for img_link in self.yk_img_link_list:
            root.data.insert(0, {
                "source": img_link[0],
                "size_hint": (0.5, None),
                "height": kivy.metrics.dp(150),
                "allow_stretch": True,
                "keep_ratio": False,
                'text': img_link[1],
            })

    def add_all_links(self):
        """全部动漫添加新图片、新视频链接"""
        print("视频看看", self.children[0])
        root = self.children[0].ids['videoRecycleView']
        # 如果有元素，则删除
        if root.data:
            del root.data[:]
        for img_link in self.img_link_list:
            root.data.insert(0, {
                "source": img_link[0],
                "size_hint": (0.5, None),
                "height": kivy.metrics.dp(150),
                "allow_stretch": True,
                "keep_ratio": False,
                'text': img_link[1],
            })

    def add_is_status_links(self, status):
        """
        连载动漫
        :return:
        """
        # self.children[0].ids['videoRecycleView'].clear_widgets()
        root = self.children[0].ids['videoRecycleView']
        if root.data:
            del root.data[:]
        for img_link in self.img_link_list:
            if img_link[2] == status:
                print(img_link[0], img_link[1], img_link[2])
                root.data.insert(0, {
                    "source": img_link[0],
                    "size_hint": (0.4, None),
                    "height": kivy.metrics.dp(150),
                    "allow_stretch": True,
                    "keep_ratio": False,
                    'text': img_link[1],
                })

    def bilibili_screen(self):
        # 切换屏幕到哔哩哔哩
        self.current = "bilibili_video"

    def tencent_screen(self):
        # 切换屏幕到腾讯
        self.current = "tencent_video"

    def youku_screen(self):
        # 切换屏幕到优酷
        self.current = "youku_video"

    def on_key(self, window, key, *args):
        if key == 27:  # 这个27是ESCAPE退出键的ASCII码值
            if self.current_screen.name == "anime_info_show":
                # 清除子控件
                self.children[0].ids['grid_button'].clear_widgets()
                self.current = "select_video"
            elif self.current_screen.name == "play_spider_video":
                self.children[0].ids['video_play'].state = "stop"
                self.current = "anime_info_show"


class SelectableRecycleGridLayout(FocusBehavior, LayoutSelectionBehavior,
                                  RecycleGridLayout):
    '''
    Adds selection and focus behaviour to the view.
    添加选择和焦点行为到视图。
    '''

    def __init__(self, **kwargs):
        super(SelectableRecycleGridLayout, self).__init__(**kwargs)


class SelectableVideoAsyncImage(RecycleDataViewBehavior, AsyncImage):
    '''
    Add selection support to the Label
    将选择支持添加到标签--->进行视频选择
    '''

    def __init__(self, **kwargs):
        super(SelectableVideoAsyncImage, self).__init__(**kwargs)
        self.index = None
        self.selected = BooleanProperty(False)
        self.selectable = BooleanProperty(True)

    def refresh_view_attrs(self, rv, index, data):
        '''
        Catch and handle the view changes， refresh-->更新, attrs-->属性
        捕获并处理视图更改
        '''
        self.index = index
        # print("index", rv)
        return super(SelectableVideoAsyncImage, self).refresh_view_attrs(
            rv, index, data)

    def on_touch_down(self, touch):
        '''
        Add selection on touch down, touch-->触摸
        在触摸时添加选择
        '''
        # if super(SelectableAsyncImage, self).on_touch_down(touch):
        #     return True
        if self.collide_point(*touch.pos) and self.selectable:
            return self.parent.select_with_touch(self.index, touch)

    def apply_selection(self, rv, index, is_selected):
        '''
        Respond to the selection of items in the view. apply-->请求，应用, selection-->选择
        响应视图中项目的选择。
        '''
        self.selected = is_selected
        if is_selected:
            print("增加选择 {0}".format(rv.data[index]))
            print("七个刚好找到Manager", self.parent.parent.parent.parent.parent.parent.parent)
            if self.parent.parent.parent.parent.parent.parent.parent.current_screen.name == "bilibili_video":
                # 视频链接列表
                link_video = []
                # 可以使用text属性来动漫安排链接
                print("查看名字", rv.data[index]['text'])
                self.parent.parent.parent.parent.parent.parent.parent.current = "anime_info_show"
                # 需要传入与图片名字相符合的动漫集数进去
                for anime_name in self.parent.parent.parent.parent.parent.parent.parent.video_link_list:
                    if rv.data[index]['text'] == anime_name[0]:
                        link_video.append((anime_name[1], anime_name[2]))
                print("查看是否有重复", link_video)
                # 去重,可能存在重复的集数(数据库没处理好)
                link_video = list(set(link_video))
                # 对获取到的集数进行排序
                link_video.sort(key=self.take_first)
                print("查看是否升序排序", link_video)
                # 给集数页面展示图片
                self.parent.parent.parent.parent.parent.parent.parent.children[0].ids['img_show'].source = \
                    rv.data[index]['source']
                self.parent.parent.parent.parent.parent.parent.parent.children[0].ids['anime_name_show'].text = \
                    rv.data[index]['text']
                self.parent.parent.parent.parent.parent.parent.parent.children[0].add_play_button(link_video)
            elif self.parent.parent.parent.parent.parent.parent.parent.current_screen.name == "tencent_video":
                # 可以使用text属性来动漫安排链接
                print("查看名字", rv.data[index]['text'])
                # 视频链接列表
                tx_link_video = []
                self.parent.parent.parent.parent.parent.parent.parent.current = "anime_info_show"
                # 需要传入与图片名字相符合的动漫集数进去
                for anime_name in self.parent.parent.parent.parent.parent.parent.parent.tx_video_link_list:
                    if rv.data[index]['text'] == anime_name[0]:
                        tx_link_video.append((anime_name[1], anime_name[2]))
                print("查看是否有重复", tx_link_video)
                # 去重,可能存在重复的集数(数据库没处理好)
                tx_link_video = list(set(tx_link_video))
                # 对获取到的集数进行排序
                tx_link_video.sort(key=self.take_first)
                print("查看是否升序排序", tx_link_video)
                # 给集数页面展示图片
                self.parent.parent.parent.parent.parent.parent.parent.children[0].ids['img_show'].source = \
                    rv.data[index]['source']
                self.parent.parent.parent.parent.parent.parent.parent.children[0].ids['anime_name_show'].text = \
                    rv.data[index]['text']
                self.parent.parent.parent.parent.parent.parent.parent.children[0].add_play_button(tx_link_video)
            elif self.parent.parent.parent.parent.parent.parent.parent.current_screen.name == "youku_video":
                # 可以使用text属性来动漫安排链接
                print("查看名字", rv.data[index]['text'])
                # 视频链接列表
                yk_link_video = []
                self.parent.parent.parent.parent.parent.parent.parent.current = "anime_info_show"
                # 需要传入与图片名字相符合的动漫集数进去
                for anime_name in self.parent.parent.parent.parent.parent.parent.parent.yk_video_link_list:
                    if rv.data[index]['text'] == anime_name[0]:
                        yk_link_video.append((anime_name[1], anime_name[2]))
                print("查看是否有重复", yk_link_video)
                # 去重,可能存在重复的集数(数据库没处理好)
                yk_link_video = list(set(yk_link_video))
                # 对获取到的集数进行排序
                yk_link_video.sort(key=self.take_first)
                print("查看是否升序排序", yk_link_video)
                # 给集数页面展示图片
                self.parent.parent.parent.parent.parent.parent.parent.children[0].ids['img_show'].source = \
                    rv.data[index]['source']
                self.parent.parent.parent.parent.parent.parent.parent.children[0].ids['anime_name_show'].text = \
                    rv.data[index]['text']
                self.parent.parent.parent.parent.parent.parent.parent.children[0].add_play_button(yk_link_video)
            # 取消当前节点选择
            self.parent.clear_selection()
        else:
            # print("移出选择 {0}".format(rv.data[index]))
            pass

    def take_first(self, element_list):
        """
        获取列表的第一个元素， take-->拿，取
        :param element_list: 传入的元素列表
        :return:
        """
        return element_list[0]


class VideoSelectScreen(Screen):
    """
        视频区域类
    """

    def __init__(self, **kwargs):
        super(VideoSelectScreen, self).__init__(**kwargs)


class BiliBiliScreen(Screen):
    """
        视频区域类
    """

    def __init__(self, **kwargs):
        super(BiliBiliScreen, self).__init__(**kwargs)


class TencentScreen(Screen):
    """
        视频区域类
    """

    def __init__(self, **kwargs):
        super(TencentScreen, self).__init__(**kwargs)


class YoukuScreen(Screen):
    """
        视频区域类
    """

    def __init__(self, **kwargs):
        super(YoukuScreen, self).__init__(**kwargs)


class AnimeInfoShow(Screen):
    """
    动漫信息介绍
    """

    def __init__(self, **kwargs):
        super(AnimeInfoShow, self).__init__(**kwargs)

    def add_play_button(self, link_list):
        """
        添加视频播放选集按钮
        :param link_list: 视频链接列表
        """
        print("视频播放按钮", self.parent.query_data)
        for link in link_list:
            btn = Button(
                text=str(link[0]),
                size_hint_x=None,
                size_hint_y=None,
                width=kivy.metrics.dp(80),
                height=kivy.metrics.dp(40),
                color=(0.3, 0.6, 0.9),
                background_color=(0.4, 0.3, 0.9, 1.0),
            )
            # 将按钮添加至网格布局中
            self.ids['grid_button'].add_widget(btn)
            # 为每个按钮添加一个事件, partial这返回一个带功能的新函数
            btn.bind(on_release=partial(self.in_play_screen, link[1]))

    def in_play_screen(self, link, event):
        """
        按钮点击之后转到视频播放屏幕play_spider_video
        :param event:
        :return:
        """
        # 拼接动漫播放url地址
        link = '../' + link
        print(link, event)
        # 跳转至play_spider_video窗口
        self.parent.current = 'play_spider_video'
        self.parent.children[0].ids['video_play'].source = link
        self.parent.children[0].ids['video_play'].state = "play"


class PlaySpiderVideo(Screen):
    """
        播放视频窗口
    """

    def __init__(self, **kwargs):
        super(PlaySpiderVideo, self).__init__(**kwargs)


kv = Builder.load_file("videogui.kv")


class VideoSpiderGuiApp(App):

    def __init__(self, **kwargs):
        super(VideoSpiderGuiApp, self).__init__(**kwargs)

    def build(self):
        # 调用连接server函数

        return kv

    def on_start(self):
        # android.stop_service() # Kill zombine service from previous app instances

        Config.set('kivy', 'exit_on_escape', 0)


if __name__ == "__main__":
    VideoSpiderGuiApp().run()
